<?php
define('Criteria_AND', 100);
define('Criteria_OR', 200);
define('Criteria_NONE', 0);
class XCriteria{
	protected $criterias = array();
	protected $projections = array();
	protected $parentCriteria = null;
	protected $type = Criteria_NONE;
	
	/**
	 * @return XCriteria
	 */
	public function cloneCriteria(){
		return clone $this;
	}
		
	/**
	 * @return array
	 */	
	public function criterias(){
		return $this->criterias;
	}
	
	/**
	 * @return array
	 */	
	public function projections(){
		return $this->projections;
	}	
	
	public function type(){
		return $this->type;
	}
	
	/**
	 * @return XCriteria
	 */	
	public function setType($type){
		$this->type = $type;
		return $this;
	}	
	
	/**
	 * @return XCriteria
	 */	
	public function parentCriteria(){
		return $this->parentCriteria;
	}
	
	/**
	 * @return XCriteria
	 */	
	public function setParentCriteria($parentCriteria){
		$this->parentCriteria = $parentCriteria;
		return $this;
	}
	
	public function addAnd(XCriteria $criteria){
		$criteria->setType(Criteria_AND);
		$criteria->setParentCriteria($this);
		$this->criterias[] = $criteria;
		return $this;
	}
	
	public function addOr(XCriteria $criteria){
		$criteria->setType(Criteria_OR);
		$criteria->setParentCriteria($this);
		$this->criterias[] = $criteria;
		return $this;
	}
	
	/**
	 * @return XCriteria
	 */
	public function eq($field, $value){
		if(is_array($value)){
			return $this->addCriterion(XCriterion::in($field, $value));
		}
		return $this->addCriterion(XCriterion::eq($field, $value));
	}
	
	/**
	 * @return XCriteria
	 */	
	public function example(XModel $example){
		return $this->addCriterion(XCriterion::example($example));
	}
	
	/**
	 * @return XCriteria
	 */
	public function regexp($key, $value){
		return $this->addCriterion(XCriterion::regexp($example));
	}	
	
	/**
	 * @return XCriteria
	 */
	public function not($field, $value){
		return $this->addCriterion(XCriterion::not($field, $value));
	}
	
	/**
	 * @return XCriteria
	 */
	public function greater($field, $value){
		return $this->addCriterion(XCriterion::greater($field, $value));
	}
	
	/**
	 * @return XCriteria
	 */
	public function notGreater($field, $value){
		return $this->addCriterion(XCriterion::notGreater($field, $value));
	}	
	
	/**
	 * @return XCriteria
	 */
	public function less($field, $value){
		return $this->addCriterion(XCriterion::less($field, $value));
	}	
	
	/**
	 * @return XCriteria
	 */
	public function notLess($field, $value){
		return $this->addCriterion(XCriterion::notLess($field, $value));
	}
	
	/**
	 * @return XCriteria
	 */
	public function in($field, array $value){
		return $this->addCriterion(XCriterion::in($field, $value));
	}	
	
	/**
	 * @return XCriteria
	 */
	public function notIn($field, array $value){
		return $this->addCriterion(XCriterion::notIn($field, $value));
	}	
	
	/**
	 * @return XCriteria
	 */
	public function like($field, $value, $mode = LIKE_ANYWHERE){
		return $this->addCriterion(XCriterion::like($field, $value, $mode));
	}	
	
	/**
	 * @return XCriteria
	 */
	public function between($field, $from, $to){
		return $this->addCriterion(XCriterion::between($field, $from, $to));
	}	

	/**
	 * @return XCriteria
	 */
	public function isNull($field){
		return $this->addCriterion(XCriterion::isNull($field));
	}	
	
	/**
	 * @return XCriteria
	 */
	public function notNull($field){
		return $this->addCriterion(XCriterion::notNull($field));
	}
	
	/**
	 * @return XCriteria
	 */	
	public function addCriterion(XCriterion $criterion){
		$criterion->setParentCriteria($this);
		$this->criterias[] = $criterion;
		return $this;
	}
	
	/**
	 * @return XCriteria
	 */
	public function orderBy($field, $asc = true){
		return $this->addProjection(XProjection::order($field, $asc));
	}
	
	/**
	 * @return XCriteria
	 */	
	public function offset($offset){
		return $this->addProjection(XProjection::offset($offset));
	}
	
	/**
	 * @return XCriteria
	 */	
	public function size($size){
		return $this->addProjection(XProjection::size($size));
	}
	
	/**
	 * @return XCriteria
	 */	
	public function limit($size){
		return $this->addProjection(XProjection::size($size));
	}
	
	/**
	 * @return XCriteria
	 */	
	public function count($field = null){
		return $this->addProjection(XProjection::count($field));
	}

	/**
	 * @return XCriteria
	 */	
	public function sum($field){
		return $this->addProjection(XProjection::sum($field));
	}

	/**
	 * @return XCriteria
	 */	
	public function avg($field){
		return $this->addProjection(XProjection::avg($field));
	}
	
	/**
	 * @return XCriteria
	 */	
	public function max($field){
		return $this->addProjection(XProjection::max($field));
	}

	/**
	 * @return XCriteria
	 */	
	public function min($field){
		return $this->addProjection(XProjection::min($field));
	}
	
	/**
	 * @return XCriteria
	 */
	public function result($result){
		return $this->addProjection(XProjection::result($result));
	}	

	/**
	 * @return XCriteria
	 */	
	public function addProjection(XProjection $projection){
		$projection->setParentCriteria($this);
		$type = $projection->type();
		if($type != ORDER){			
			$this->projections[$type] = $projection;
			return $this;
		}
		if(!isset($this->projections[$type])){
			$this->projections[$type] = array($projection);
			return $this;
		}
		array_push($this->projections[$type], $projection);
		return $this;
	}
}
?>